home *** CD-ROM | disk | FTP | other *** search
- /*** OPERAND.C (c) S.Enjoji ***/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- int getdata(void);
- void mod0(char *p);
- void mod12(char *p);
- void imm(char *p);
- void simm8(char *p);
- void imm8(char *p);
- void imm48(char *p);
- void offset(char *p);
- void disp(char *p);
-
- extern char op1[], op2[], op3[];
- extern int mod, reg, rm, op32, ad32, oprsize;
- extern unsigned long addr;
- char *regname[3][8] = {
- "AL","CL","DL","BL","AH","CH","DH","BH",
- "AX","CX","DX","BX","SP","BP","SI","DI",
- "EAX","ECX","EDX","EBX","ESP","EBP","ESI","EDI"
- };
- char *sregname[8] = {"ES","CS","SS","DS","FS","GS","HS","IS"};
- char scale[4] = {1,2,4,8};
-
- void operand(int t, char *p)
- {
- if(t == 1) { /* operand is reg */
- sprintf(p,"%%%s",regname[oprsize][reg]);
- } else if(t == 2) { /* operand is r/m */
- if(mod == 3) {
- sprintf(p,"%%%s",regname[oprsize][rm]);
- } else if(mod == 0) {
- mod0(p);
- } else {
- mod12(p);
- }
- } else if(t == 3) { /* operand is sreg */
- sprintf(p,"%%%s",sregname[reg]);
- } else if(t == 4) { /* operand is CRn reg */
- sprintf(p,"%%CR%d",reg);
- } else if(t == 5) { /* operand is DBn reg */
- sprintf(p,"%%DB%d",reg);
- } else if(t == 6) { /* operand is TRn reg */
- sprintf(p,"%%TR%d",reg);
- } else if(t <= 0x17) { /* レジスタ直接指定、modrm 無し */
- sprintf(p,"%%%s",regname[oprsize][t - 0x10]);
- } else if(t <= 0x1f) { /* セグメントレジスタ直接指定、modrm 無し */
- sprintf(p,"%%%s",sregname[t - 0x18]);
- } else if(t == 0x20) { /* DX */
- sprintf(p,"(%%DX)");
- } else if(t == 0x21) { /* CL */
- sprintf(p,"%%CL");
- } else if(t == 0x22) { /* 1 */
- sprintf(p,"$1");
- } else if(t == 0x80) { /* イミディエットデータ */
- imm(p);
- } else if(t == 0x81) { /* アドレスオフセット */
- offset(p);
- } else if(t == 0x82) { /* ディスプレースメント */
- disp(p);
- } else if(t == 0x83) { /* Sign extended immediate byte */
- simm8(p);
- } else if(t == 0x84) { /* Immediate byte */
- imm8(p);
- } else if(t == 0x85) { /* Immediate word:long */
- imm48(p);
- }
- }
-
- void mod0(char *p)
- {
- int ss,index,base,d;
-
- if(rm == 4) {
- d = getdata();
- base = d % 8;
- index = (d >> 3) % 8;
- ss = d >> 6;
- sprintf(p,"(%%%s,%%%s,%d)",
- regname[2][base],regname[2][index],scale[ss]);
- } else if(rm == 5) {
- offset(p);
- } else {
- sprintf(p,"(%%%s)",regname[2][rm]);
- }
- }
-
- void mod12(char *p)
- {
- int ss,index,base,d,d0,d1,d2,d3;
-
- if(rm == 4) {
- d = getdata();
- base = d % 8;
- index = (d >> 3) % 8;
- ss = d >> 6;
- d0 = getdata();
- if(mod == 1) {
- sprintf(p,"0x%02X(%%%s,%%%s,%d)",
- d0,regname[2][base],regname[2][index],scale[ss]);
- } else {
- d1 = getdata();
- d2 = getdata();
- d3 = getdata();
- sprintf(p,"0x%02X%02X%02X%02X(%%%s,%%%s,%d)",
- d3,d2,d1,d0,regname[2][base],regname[2][index],scale[ss]);
- }
- } else {
- d0 = getdata();
- if(mod == 1) {
- sprintf(p,"0x%02X(%%%s)",d0,regname[2][rm]);
- } else {
- d1 = getdata();
- d2 = getdata();
- d3 = getdata();
- sprintf(p,"0x%02X%02X%02X%02X(%%%s)",d3,d2,d1,d0,regname[2][rm]);
- }
- }
- }
-
- void imm(char *p)
- {
- int d0,d1,d2,d3;
-
- d0 = getdata();
- if(oprsize == 0) {
- sprintf(p,"$0x%02X",d0);
- } else if(oprsize == 1) {
- d1 = getdata();
- sprintf(p,"$0x%02X%02X",d1,d0);
- } else {
- d1 = getdata();
- d2 = getdata();
- d3 = getdata();
- sprintf(p,"$0x%02X%02X%02X%02X",d3,d2,d1,d0);
- }
- }
-
- void simm8(char *p)
- {
- int d0;
-
- d0 = getdata();
- if(d0 < 0x80) {
- sprintf(p,"$%d",d0);
- } else {
- d0 = 0x100 - d0;
- sprintf(p,"$-%d",d0);
- }
- }
-
- void imm8(char *p)
- {
- int d0;
-
- d0 = getdata();
- sprintf(p,"$0x%02X",d0);
- }
-
- void imm48(char *p)
- {
- int d0,d1,d2,d3,d4,d5;
-
- d0 = getdata();
- d1 = getdata();
- d2 = getdata();
- d3 = getdata();
- d4 = getdata();
- d5 = getdata();
- sprintf(p,"$0x%02X%02X,$0x%02X%02X%02X%02X",d5,d4,d3,d2,d1,d0);
- }
-
- void offset(char *p)
- {
- int d0,d1,d2,d3;
-
- d0 = getdata();
- d1 = getdata();
- d2 = getdata();
- d3 = getdata();
- sprintf(p,"0x%02X%02X%02X%02X",d3,d2,d1,d0);
- }
-
- void disp(char *p)
- {
- int d0,d1,d2;
- unsigned long daddr, d;
-
- d0 = getdata();
- if(oprsize == 0) {
- daddr = addr + ((d0 < 0x80) ? d0 : d0-0x100);
- } else if(oprsize == 1) {
- d = getdata();
- d = (d << 8) + d0;
- daddr = addr + ((d < 0x8000) ? d : d-0x10000);
- } else {
- d1 = getdata();
- d2 = getdata();
- d = getdata();
- d = (d << 8) + d2;
- d = (d << 8) + d1;
- d = (d << 8) + d0;
- daddr = addr + d;
- }
- sprintf(p,"_%08lX",daddr);
- }
-